/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.modules.form.editors2; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.*; import java.util.Vector; import java.util.Enumeration; import java.util.ResourceBundle; import java.text.MessageFormat; import javax.swing.*; import javax.swing.border.*; import javax.swing.event.*; import org.openide.awt.SplittedPanel; import org.openide.nodes.*; import org.openide.explorer.propertysheet.PropertySheetView; import org.openide.explorer.view.ListView; import org.openide.explorer.*; import org.openide.nodes.*; import org.openide.util.actions.SystemAction; import org.openide.util.HelpCtx; import org.openide.util.NbBundle; import org.netbeans.modules.form.compat2.border.*; import org.netbeans.modules.form.palette.*; /** * A property editor for swing border class. * * This editor should be in some subpackage under developerx package, * but it is not possible now, because this package is only package where are * property editors searched. * * @author Petr Hamernik */ public final class BorderEditor extends PropertyEditorSupport implements org.openide.explorer.propertysheet.editors.XMLPropertyEditor { // [PENDING - not for now] /** Icon bases for unknown border node. */ private static final String UNKNOWN_BORDER_BASE = "org/netbeans/modules/form/editors2/unknownBorder"; // NOI18N /** Icon bases for no border node. */ private static final String NO_BORDER_BASE = "org/netbeans/modules/form/editors2/nullBorder"; // NOI18N private static final ResourceBundle bundle = NbBundle.getBundle(BorderEditor.class); private static final String NO_BORDER = bundle.getString("LAB_NoBorder"); private static final MessageFormat UNKNOWN_BORDER = new MessageFormat(bundle.getString("LAB_FMT_UnknownBorder")); // variables .................................................................................. private BorderPanel bPanel; private Border current; // init ....................................................................................... public BorderEditor() { bPanel = null; current = null; } // main methods ....................................................................................... public Object getValue () { return current; } public void setValue (Object object) { if (object == null) current = null; if (object instanceof Border) { current = (Border) object; if (bPanel != null) { bPanel.setValue(current); } } } public String getAsText () { if (current == null) { return NO_BORDER; } else if (current instanceof DesignBorder) { BorderInfo info = ((DesignBorder)current).getInfo(); if (info==null) return null; // NOI18N return info.getDisplayName (); } else { return org.openide.util.Utilities.getShortClassName (current.getClass ()); } } public void setAsText (String string) { } public String getJavaInitializationString () { if (current == null) { return null; // no code to generate } else { if (current instanceof DesignBorder) { StringBuffer buf = new StringBuffer(); ((DesignBorder)current).getInfo().generateCode(buf); return buf.toString(); } else { return null; // no code to generate } } } public boolean supportsCustomEditor () { return true; } public Component getCustomEditor () { if (bPanel == null) { bPanel = new BorderPanel(); bPanel.setValue(current); } return bPanel; } // innerclasses ............................................................................................ final class BorderPanel extends ExplorerPanel implements PropertyChangeListener, VetoableChangeListener { ListView listView; PropertySheetView sheetView; NoBorderNode noBorder; UnknownBorderNode unknownBorder; Node root; static final long serialVersionUID =-2613206277499334010L; BorderPanel() { root = new AbstractNode (new Children.Array ()); noBorder = new NoBorderNode(); root.getChildren ().add (new Node[] { noBorder }); PropertyChangeListener pListener = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { updateBorder(getExplorerManager ().getSelectedNodes()[0]); } }; PaletteItem[] items = ComponentPalette.getDefault().getAllItems (); for (int i = 0; i < items.length; i++) { if (items[i].isBorder()) { try { BorderListNode listNode = new BorderListNode(items[i]); listNode.addPropertyChangeListener(pListener); root.getChildren ().add(new Node[] { listNode }); } catch (IllegalAccessException e) { // ignore => not added to list } catch (InstantiationException e) { // ignore => not added to list } } } getExplorerManager ().setRootContext(root); getExplorerManager ().addPropertyChangeListener(this); getExplorerManager ().addVetoableChangeListener(this); setLayout(new BorderLayout ()); setBorder(new EmptyBorder(5, 5, 5, 5)); SplittedPanel split = new SplittedPanel(); split.setSplitType(SplittedPanel.VERTICAL); split.setSplitAbsolute(false); split.setSplitPosition(40); listView = new ListView(); JPanel ppp = new JPanel(); ppp.setBorder(new TitledBorder(bundle.getString("LAB_AvailableBorders"))); ppp.setLayout(new BorderLayout()); ppp.add(BorderLayout.CENTER, listView); split.add(ppp, SplittedPanel.ADD_TOP); sheetView = new PropertySheetView(); split.add(sheetView, SplittedPanel.ADD_BOTTOM); add(BorderLayout.CENTER, split); } public org.openide.util.HelpCtx getHelpCtx () { return new HelpCtx (BorderPanel.class); } public Dimension getPreferredSize () { return new Dimension (360, 440); } void setValue(Border border) { if (border == null) { try { getExplorerManager ().setSelectedNodes(new Node[] { noBorder }); } catch (PropertyVetoException e) { } } else if (border instanceof DesignBorder) { BorderInfo info = ((DesignBorder)border).getInfo(); if (unknownBorder != null) { root.getChildren ().remove (new Node[] { unknownBorder }); unknownBorder = null; } Node[] nodes = root.getChildren().getNodes (); for (int i = 0; i < nodes.length; i++) { if (nodes[i] instanceof BorderListNode) { BorderInfo nodeBorderInfo = ((BorderListNode)nodes[i]).getDesignBorder().getInfo(); if (nodeBorderInfo.getClass().isAssignableFrom(info.getClass())) { ((BorderListNode)nodes[i]).setDesignBorder((DesignBorder)border); try { getExplorerManager ().setSelectedNodes(new Node[] { nodes[i] }); } catch (PropertyVetoException e) { } return; } } } } else { if (unknownBorder != null) { unknownBorder.setBorder(border); } else { unknownBorder = new UnknownBorderNode(border); root.getChildren ().add(new Node[] { unknownBorder }); try { getExplorerManager ().setSelectedNodes(new Node[] { unknownBorder }); } catch (PropertyVetoException e) { } } } } void updateBorder(Node node) { if (node instanceof NoBorderNode) { BorderEditor.this.current = null; } else if (node instanceof UnknownBorderNode) { BorderEditor.this.current = ((UnknownBorderNode) node).getBorder(); } else { BorderEditor.this.current = ((BorderListNode) node).getDesignBorder(); } BorderEditor.this.firePropertyChange(); } public void propertyChange(PropertyChangeEvent evt) { if (ExplorerManager.PROP_SELECTED_NODES.equals(evt.getPropertyName())) { Node[] nodes = (Node[]) evt.getNewValue(); switch (nodes.length) { case 0: try { getExplorerManager ().setSelectedNodes(new Node[] { noBorder }); } catch (PropertyVetoException e) { } break; case 1: updateBorder(nodes[0]); break; } } } public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException { if (ExplorerManager.PROP_SELECTED_NODES.equals(evt.getPropertyName())) { Node[] nodes = (Node[]) evt.getNewValue(); if (nodes.length != 1) throw new PropertyVetoException("", evt); // NOI18N } } } static final class BorderListNode extends AbstractNode implements PropertyChangeListener { private PaletteItem paletteItem; private DesignBorder designBorder; BorderListNode(PaletteItem paletteItem) throws IllegalAccessException, InstantiationException { super(Children.LEAF); this.paletteItem = paletteItem; designBorder = paletteItem.createBorder (); setName (designBorder.getInfo ().getDisplayName ()); } /** Find an icon for this node (in the closed state). * @param type constant from {@link java.beans.BeanInfo} * @return icon to use to represent the node */ public Image getIcon (int type) { return designBorder.getInfo ().getIcon (type); } /** Find an icon for this node (in the open state). * This icon is used when the node may have children and is expanded. * * @param type constant from {@link java.beans.BeanInfo} * @return icon to use to represent the node when open */ public Image getOpenedIcon (int type) { return getIcon (type); } /** Creates property set for this node */ protected Sheet createSheet () { Node.Property[] props = designBorder.getInfo().getProperties(); Sheet.Set propsSet = Sheet.createPropertiesSet (); propsSet.put(props); Sheet sheet = new Sheet (); sheet.put (propsSet); for (int i = 0; i < props.length; i++) { if (props[i] instanceof BorderInfoSupport.BorderProp) { ((BorderInfoSupport.BorderProp)props[i]).setPropertyChangeListener(this); } } return sheet; } public DesignBorder getDesignBorder() { return designBorder; } public void setDesignBorder(DesignBorder border) { designBorder = border; } public void propertyChange(PropertyChangeEvent evt) { designBorder = new DesignBorder(designBorder.getInfo()); firePropertyChange("", null, null); // NOI18N } } static final class NoBorderNode extends AbstractNode { /** generated Serialized Version UID */ static final long serialVersionUID = 3454994916520236035L; NoBorderNode() { super(Children.LEAF); setDisplayName(NO_BORDER); setIconBase (NO_BORDER_BASE); } } static final class UnknownBorderNode extends AbstractNode { /** generated Serialized Version UID */ static final long serialVersionUID = 3063018048992659100L; private Border border; UnknownBorderNode(Border border) { super(Children.LEAF); setBorder(border); setIconBase (UNKNOWN_BORDER_BASE); } void setBorder(Border border) { this.border = border; String longName = border.getClass().getName(); int dot = longName.lastIndexOf('.'); String shortName = (dot < 0) ? longName : longName.substring(dot + 1); setDisplayName(UNKNOWN_BORDER.format(new Object[] { longName, shortName })); } Border getBorder() { return border; } } //-------------------------------------------------------------------------- // XMLPropertyEditor implementation public static final String XML_BORDER = "Border"; // NOI18N public static final String ATTR_INFO = "info"; // NOI18N /** Called to load property value from specified XML subtree. If succesfully loaded, * the value should be available via the getValue method. * An IOException should be thrown when the value cannot be restored from the specified XML element * @param element the XML DOM element representing a subtree of XML from which the value should be loaded * @exception IOException thrown when the value cannot be restored from the specified XML element */ public void readFromXML (org.w3c.dom.Node element) throws java.io.IOException { if (!XML_BORDER.equals (element.getNodeName ())) { throw new java.io.IOException (); } org.w3c.dom.NamedNodeMap attributes = element.getAttributes (); try { String info = attributes.getNamedItem (ATTR_INFO).getNodeValue (); info = org.openide.util.Utilities.translate(info); BorderInfo bi = (BorderInfo)org.openide.TopManager.getDefault ().currentClassLoader ().loadClass(org.openide.util.Utilities.translate(info)).newInstance (); org.w3c.dom.NodeList children = element.getChildNodes (); for (int i = 0; i < children.getLength (); i++) { if (children.item (i).getNodeType () == org.w3c.dom.Node.ELEMENT_NODE) { bi.readFromXML (children.item (i)); break; } } setValue (new DesignBorder (bi)); } catch (Exception e) { throw new java.io.IOException (); } } /** Called to store current property value into XML subtree. The property value should be set using the * setValue method prior to calling this method. * @param doc The XML document to store the XML in - should be used for creating nodes only * @return the XML DOM element representing a subtree of XML from which the value should be loaded */ public org.w3c.dom.Node storeToXML(org.w3c.dom.Document doc) { if (getValue () instanceof DesignBorder) { org.w3c.dom.Element el = doc.createElement (XML_BORDER); BorderInfo info = ((DesignBorder)getValue ()).getInfo (); el.setAttribute (ATTR_INFO, info.getClass ().getName ()); org.w3c.dom.Node borderNode = info.storeToXML (doc); if (borderNode != null) el.appendChild (borderNode); return el; } else { return null; // cannot be saved } } } /* * Log * 18 Gandalf 1.17 1/24/00 Pavel Buzek #5490 fixed - getText * works for null border * 17 Gandalf 1.16 1/20/00 Pavel Buzek * 16 Gandalf 1.15 1/13/00 Ian Formanek NOI18N #2 * 15 Gandalf 1.14 1/10/00 Ian Formanek provides better * getAsText * 14 Gandalf 1.13 12/3/99 Pavel Buzek in readFromXML creating * instance with currentClassLoader * 13 Gandalf 1.12 11/27/99 Patrik Knakal * 12 Gandalf 1.11 11/24/99 Pavel Buzek added support for saving * in XML format * 11 Gandalf 1.10 11/5/99 Jesse Glick Context help jumbo * patch. * 10 Gandalf 1.9 10/22/99 Ian Formanek NO SEMANTIC CHANGE - Sun * Microsystems Copyright in File Comment * 9 Gandalf 1.8 8/13/99 Jaroslav Tulach ExplorerManager change * 8 Gandalf 1.7 8/9/99 Ian Formanek Generated Serial Version * UID * 7 Gandalf 1.6 8/2/99 Ian Formanek preview of XML * serialization of borders * 6 Gandalf 1.5 7/8/99 Jesse Glick Context help. * 5 Gandalf 1.4 6/11/99 Jaroslav Tulach System.out commented * 4 Gandalf 1.3 6/9/99 Ian Formanek ---- Package Change To * org.openide ---- * 3 Gandalf 1.2 5/30/99 Ian Formanek Finalized * 2 Gandalf 1.1 5/24/99 Ian Formanek * 1 Gandalf 1.0 5/14/99 Ian Formanek * $ */